<!DOCTYPE html>
<html>
<head>
    <title>Touch Adjustment : Event triggered widgets - bug 78801</title>
    <script src="../resources/js-test.js"></script>
    <script src="resources/touchadjustment.js"></script>
    <style>
        .box { border: 1px solid black; border-radius: 5px 5px; margin: 1em; width: 40em; }
    </style>
</head>

<body>

<div id=sandbox>
    <script>
        function triggerInput() {
            var element = event.srcElement;
            if (!element.open) {
                element.innerHTML = '<input type=text style="width: 100%"></input>'
                element.open = true;
            }
            element.firstChild.focus();
        }
    </script>

    <div id=test1 class=box tabindex=1 onfocus='triggerInput()'>
    Focus here should give a text input-field.
    </div>

    <div id=test2 class=box onmouseover='triggerInput()'> 
    Mouse-over here should give a text input-field.
    </div>

    <style>
        .box:not(:hover) .hovertriggered { visibility: hidden;}
        .box:hover .hoverfallback { display: none; }  
    </style>

    <div id=test3 class=box> 
        <span class=hoverfallback>Hovering here should give a text input-field.</span>
        <input type=text class=hovertriggered></input>
    </div>

    <div id=test4 class=box onfocus='triggerInput()'>
        <span tabindex=1> Focusing here should only give focus outline to this inner text.
        </span>
    </div>

    <div class=box>
        <span id=test5 tabindex=1> Focusing here should give a text input-field.
        </span>
    </div>

    <script>
        var element = document.getElementById('test5');
        element.addEventListener('DOMFocusIn', triggerInput, false);
    </script>
</div>

<p id='description'></p>
<div id='console'></div>

<script>
    var element;
    var adjustedNode;
    function findAbsolutePosition(node) {
        var pos = new Object();
        pos.left = 0; pos.top = 0;
        do {
            pos.left += node.offsetLeft;
            pos.top += node.offsetTop;
        } while (node = node.offsetParent);
        return pos;
    }

    function findBestClickableNode(x, y, width, height)
    {
        var adjustedNode = internals.touchNodeAdjustedToBestClickableNode(x, y, width, height, document);
        if (adjustedNode && adjustedNode.nodeType == 3) // TEXT node
            adjustedNode = adjustedNode.parentNode;
        return adjustedNode;
    }

    function testDirectTouch(element)
    {
        var touchpoint = offsetTouchPoint(findAbsoluteBounds(element), 'center', 0, 2, 2);
        adjustedNode = findBestClickableNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    }

    function testDirectFatFinger(element)
    {
        var touchpoint = offsetTouchPoint(findAbsoluteBounds(element), 'top', -5, element.clientHeight/2, (element.clientHeight+10)/2);
        adjustedNode = findBestClickableNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    }

    function testIndirectFatFinger(element)
    {
        var touchpoint = offsetTouchPoint(findAbsoluteBounds(element), 'top', 3, 5, 5);
        adjustedNode = findBestClickableNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    }

    function testTouchHit(elementid, touchType) {
        element = document.getElementById(elementid);
        touchType(element);
        shouldBe('adjustedNode.id', 'element.id');
    }

    function testTouchMiss(elementid, touchType) {
        element = document.getElementById(elementid);
        touchType(element);
        shouldNotBe('adjustedNode.id', 'element.id');
    }

    function testDirectTouches()
    {
        debug('Testing small direct hits');
        testTouchHit('test1', testDirectTouch);
        testTouchHit('test2', testDirectTouch);
        testTouchHit('test3', testDirectTouch);
        testTouchMiss('test4', testDirectTouch);
        testTouchHit('test5', testDirectTouch);
    }

    function testDirectFatFingers()
    {
        debug('Testing large direct hits');
        testTouchHit('test1', testDirectFatFinger);
        testTouchHit('test2', testDirectFatFinger);
        testTouchHit('test3', testDirectFatFinger);
        testTouchMiss('test4', testDirectFatFinger);
        testTouchHit('test5', testDirectFatFinger);
    }

    function testIndirectFatFingers()
    {
        debug('Testing large direct hits');
        testTouchHit('test1', testIndirectFatFinger);
        testTouchHit('test2', testIndirectFatFinger);
        testTouchHit('test3', testIndirectFatFinger);
        testTouchMiss('test4', testIndirectFatFinger);
        testTouchHit('test5', testIndirectFatFinger);
    }

    function runTests()
    {
        if (window.testRunner && window.internals && internals.touchNodeAdjustedToBestClickableNode) {
            description('Test various ways to trigger input-widgets. On a touch interface, all the actions should be triggerable with either a touch down or a touch tap.');
            testDirectTouches();
            testDirectFatFingers();
            testIndirectFatFingers();
            document.getElementById('sandbox').style.display = 'none';
        }
    }
    runTests();
</script>
</body>
</html>
